package com.lovol.gis.demo.common;

import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

/**
 * 空间参考系统工具
 */
public class SrsUtil {
    private CoordinateReferenceSystem sourceCRS;
    private CoordinateReferenceSystem targetCRS;

    /**
     * 定义坐标转换的源坐标系和目标坐标系
     *
     * @param srcEpsgCode 源坐标系的编码,例如 EPSG:4326
     * @param targetEpsgCode 目标坐标系的编码，例如 EPSG:3857
     * @param longitudeFirst  坐标系定义时，是否X坐标在前
     */
    public SrsUtil(String srcEpsgCode, String targetEpsgCode, boolean longitudeFirst) throws Exception {
        this.sourceCRS = CRS.decode(srcEpsgCode, longitudeFirst);
        this.targetCRS = CRS.decode(targetEpsgCode, longitudeFirst);
    }

    public SrsUtil(CoordinateReferenceSystem srcCRS, CoordinateReferenceSystem tgtCRS)  {
        this.sourceCRS = srcCRS;
        this.targetCRS = tgtCRS;
    }

    public SrsUtil(){

    }

    public void setSourceWkt(String srcWkt) throws Exception{
        this.sourceCRS = CRS.parseWKT(srcWkt);
    }

    /**
     *
     *
     * @param srcEpsgCode 源坐标系的编码，例如 EPSG:4326
     * @throws Exception
     */
    public void setSourceCode(String srcEpsgCode) throws Exception{
        this.sourceCRS = CRS.decode(srcEpsgCode, true);
    }

    public void setTargetWkt(String targetWkt) throws Exception{
        this.targetCRS = CRS.parseWKT(targetWkt);
    }

    /**
     *
     * @param targetEpsgCode 目标坐标系的编码，例如 EPSG:4326
     * @throws Exception
     */
    public void setTargetode(String targetEpsgCode) throws Exception{
        this.targetCRS = CRS.decode(targetEpsgCode, true);
    }

    public Geometry reproject(Geometry geometry) {
        Geometry reprojectGeometry = null;
        try {
            MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);
            reprojectGeometry = JTS.transform(geometry, transform);
        } catch (Exception e) {
            System.out.println(e);
        }
        return reprojectGeometry;
    }

    public Envelope reproject(Envelope envelope) {
        Envelope reprojectEnvelope = null;
        try {
            MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);
            reprojectEnvelope = JTS.transform(envelope, transform);
        } catch (Exception e) {
            System.out.println(e);
        }
        return reprojectEnvelope;
    }
}
